﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Data;
using System.Runtime.Serialization;

namespace MFTool
{
    public static class DictionaryExtend
    {
        public static DataTable ConvertDicToTable(List<Dictionary<string, object>> dicList)
        {
            DataTable dt = new DataTable();
            if (dicList.Count == 0)
                return dt;

            foreach (var colName in dicList[0].Keys)
            {
                dt.Columns.Add(colName, typeof(string));
            }

            foreach (var dicDep in dicList)
            {
                DataRow dr = dt.NewRow();
                foreach (KeyValuePair<string, object> item in dicDep)
                {
                    if (dt.Columns.Contains(item.Key))
                        dr[item.Key] = item.Value;
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }

        public static string GetValue(this Dictionary<string, object> dic, string key)
        {
            string result = string.Empty;
            if (!dic.ContainsKey(key)) return result;
            if (dic[key] == null || dic[key] == DBNull.Value) return result;
            result = dic[key].ToString();
            return result;
        }

        public static object GetObject(this Dictionary<string, object> dic, string key)
        {
            string result = string.Empty;
            if (!dic.ContainsKey(key)) return null;
            if (dic[key] == null || dic[key] == DBNull.Value) return null;
            return dic[key];
        }

        public static void SetValue(this Dictionary<string, object> dic, string key, string value)
        {
            dic[key] = value;
        }

        public static void SetValue(this Dictionary<string, object> dic, string key, object value)
        {
            dic[key] = value;
        }

        //泛型操作
        public static T GetValue<T>(this Dictionary<string, T> dic, string key)
        {
            T result = default(T);
            if (!dic.ContainsKey(key)) return result;
            result = dic[key];
            return result;
        }

        public static void SetValue<T>(this Dictionary<string, T> dic, string key, T value)
        {
            if (!dic.ContainsKey(key))
                dic.Add(key, value);
            else
                dic[key] = value;
        }

        /// <summary>
        /// 用字典填充对象 
        /// 包含try语句
        /// 如果数据匹配问题较多，可能造成性能问题
        /// </summary>
        /// <returns></returns>
        public static T ToModel<T>(this Dictionary<string, object> dic) where T : class,new()
        {
            T result = new T();

            PropertyInfo[] arrPtys = typeof(T).GetProperties();
            foreach (PropertyInfo destPty in arrPtys)
            {
                if (!dic.ContainsKey(destPty.Name))
                    continue;
                if (destPty.CanRead == false)
                    continue;
                try
                {
                    destPty.SetValue(result, dic.GetValue<object>(destPty.Name), null);
                }
                catch { }
            }
            return result;
        }

        public static string CreateInsertSql(this Dictionary<string, object> entity, SqlHelper sqlHelper, string tableName)
        {
            var entityTable = sqlHelper.ExcuteTable("select top 1 * from {0} where 1<>1".ReplaceArg(tableName));

            StringBuilder sbField = new StringBuilder();
            StringBuilder sbValue = new StringBuilder();

            foreach (var item in entity)
            {
                string name = item.Key.ToString();
                if (name == "ID")
                    continue;
                if (!entityTable.Columns.Contains(name))
                    continue;

                if (IsNullOrEmpty(item.Value)) continue;
                string value = item.Value.ToString();
                sbField.AppendFormat(",{0}", name);
                sbValue.AppendFormat(",'{0}'", value.Replace("'", "''"));
            }
            string sql = string.Format(@"INSERT INTO {0} ({1}) VALUES ({2})", tableName, sbField.ToString().TrimStart(','), sbValue.ToString().TrimStart(','));
            return sql;
        }

        public static string CreateUpdateSql(this Dictionary<string, object> entity, SqlHelper sqlHelper, string tableName, string ID)
        {
            var entityTable = sqlHelper.ExcuteTable("select top 1 * from {0} where 1<>1".ReplaceArg(tableName));

            StringBuilder sb = new StringBuilder();
            foreach (var item in entity)
            {
                string name = item.Key.ToString();
                if (name == "ID")
                    continue;
                if (!entityTable.Columns.Contains(name))
                    continue;
                if (item.Value == null)
                    continue;
                string value = item.Value.ToString();
                if (string.IsNullOrEmpty(value))
                    sb.AppendFormat(",{0}=NULL", name);
                else
                    sb.AppendFormat(",{0}='{1}'", name, value.Replace("'", "''"));
            }
            string sql = string.Format(@"UPDATE {0} SET {2} WHERE ID='{1}'", tableName, ID, sb.ToString().Trim(','));
            return sql;
        }

        public static string CreateDeleteSql(this Dictionary<string, object> entity, string tableName)
        {
            string sql = " delete from {0} where ID = '{1}' ";
            if (!entity.ContainsKey("ID") || IsNullOrEmpty(entity["ID"]))
                throw new Exception("删除语句必须指定主键");
            sql = string.Format(sql, tableName, entity["ID"].ToString());
            return sql;
        }

        static bool IsNullOrEmpty(object value)
        {
            if (value == null || value == DBNull.Value)
                return true;
            if (string.IsNullOrEmpty(value.ToString()))
                return true;
            return false;
        }
    }
}
